import { ProgressHandle, ComplateHandle } from "../utils/Utils";

export default class ResManager {
    private constructor() { }
    private static _instance: ResManager;
    public static get instance() {
        if (!this._instance) {
            this._instance = new ResManager();
        }
        return this._instance;
    }

    remoteCache = {};
    public getRes(url: string, asset?: typeof cc.Asset) {
        return cc.resources.get(url, asset);
    }
    public async loadRemote<T extends cc.Asset>(remoteUrl: string, onComplate?: ComplateHandle<T>) {
        return new Promise<cc.Asset>((resolve, reject) => {
            let res = this.remoteCache[remoteUrl];
            if (res) {
                if (onComplate)
                    onComplate(null, res);
                resolve(res);
            }else{
                if (remoteUrl.endsWith('.png')) {
                    cc.assetManager.loadRemote(remoteUrl, (err, asset: T) => {
                        this.remoteCache[remoteUrl] = asset;
                        if (onComplate)
                            onComplate(err, asset);
                        resolve(asset);
                    });
                } else {
                    cc.assetManager.loadRemote(remoteUrl, { ext: '.png' }, (err, asset: T) => {
                        this.remoteCache[remoteUrl] = asset;
                        if (onComplate)
                            onComplate(err, asset);
                        resolve(asset);
                    });
                }
            }
        });
    }
    public async loadDir(url: string, onProgress?: ProgressHandle, onComplate?: ComplateHandle<cc.Asset[]>) {
        return new Promise<cc.Asset[]>((resolve, reject) => {
            cc.resources.loadDir(url, onProgress, (err, assets: cc.Asset[]) => {
                for (const iterator of assets) {
                    this.addRef(iterator);
                }
                if (err)
                    reject();
                else
                    resolve(assets);
                if (onComplate)
                    onComplate(err, assets);
            });
        });

    }
    public load<T extends cc.Asset>(url: string, onProgress?: ProgressHandle, onComplate?: ComplateHandle<T>) {
        cc.resources.load(url, onProgress, (err, asset: T) => {

            this.addRef(asset);
            if (onComplate)
                onComplate(err, asset);
        });
    }
    public loadArr<T extends cc.Asset>(urls: string[], onProgress?: ProgressHandle, onComplate?: ComplateHandle<T[]>) {
        cc.resources.load<T>(urls, onProgress, (err, assets: T[]) => {
            for (const iterator of assets) {
                this.addRef(iterator);
            }
            if (onComplate)
                onComplate(err, assets);
        });
    }
    public addRef(asset: cc.Asset) {
        asset.addRef();
    }
    public releaseAsset(asset: cc.Asset) {
        cc.assetManager.releaseAsset(asset);
        asset.decRef();
        asset = null;
    }
    public release(url: string, assetType?: typeof cc.Asset) {
        let asset = cc.resources.get(url, assetType);
        cc.assetManager.releaseAsset(asset);
        asset.decRef();
        asset = null;
    }
    public reduceRef(asset: cc.Asset) {
        asset.decRef();
        asset = null;
    }
}
